<!--
 * @Author: ZhaoZhiqi
 * @Date: 2024-05-10 15:09:08
 * @LastEditors: ZhaoZhiqi
 * @LastEditTime: 2024-09-02 10:49:04
 * @Description: 合同组件
 * @FilePath: \parking-mini\src\components\Contract.vue
-->
<template>
    <div class="contract-container">
        <!-- 合同合成画布 -->
        <wxml-to-canvas width="300" height="1228" class="widget"></wxml-to-canvas>

        <u-popup :show="visible" :round="10" closeable @close="$emit('close')">
            <div class="contract-modal">
                <div class="contract-content">
                    <!-- 合同内容 -->
                    <div class="contract-img-box">
                        <!-- 合同内容图片 -->
                        <img mode="aspectFit" class="contract-img" :src="imgs.contract" />
                        <!-- 停车场名称 -->
                        <div class="contract-parking-name">{{ info.dadaParkName }}</div>
                        <!-- 乙方姓名 -->
                        <div class="contract-name">{{ info.fullName }}</div>
                        <!-- 乙方身份证 -->
                        <div class="contract-id">{{ info.idNumber }}</div>
                        <!-- 乙方联系方式 -->
                        <div class="contract-phone">{{ info.phone }}</div>
                        <!-- 乙方车牌号 -->
                        <div class="contract-plate">{{ info.carNumber }}</div>
                        <!-- 服务月数 -->
                        <div class="contract-month">{{ info.number }}</div>
                        <!-- 开始日期 -->
                        <div class="contract-start">{{ info.beginTime }}</div>
                        <!-- 结束日期 -->
                        <div class="contract-end">{{ info.endTime }}</div>
                        <!-- 购买费用 -->
                        <div class="contract-total-price">{{ info.price * info.number }}</div>
                        <!-- 月卡单价 -->
                        <div class="contract-price">{{ info.price }}</div>
                        <!-- 月卡单价 大写 -->
                        <div class="contract-price-upper">{{ upperMoney(info.price) }}</div>
                        <!-- 签订日期 甲方 -->
                        <div class="contract-time1">{{ today }}</div>
                        <!-- 签订日期 乙方 -->
                        <!-- <div class="contract-time2">{{ today }}</div> -->
                        <!-- 签名图片 -->
                        <img mode="aspectFit" class="signature-img" :src="url" />
                    </div>
                </div>
                <div class="contract-footer">
                    <div v-if="url" class="contract-btn cancel" @click="reSign">重新签名</div>
                    <div v-if="url" class="contract-btn confirm" @click="confirm">确认提交</div>
                    <div v-else class="contract-btn confirm" @click="signatureVisible = true">去签名</div>
                </div>
            </div>

            <Signature :visible="signatureVisible" @close="signatureVisible = false" @success="onSuccess"></Signature>
        </u-popup>
    </div>
</template>
<script>
import { baseUrl } from "../api/baseUrl";
import Signature from "./Signature.vue";
import wxmlToCanvas from "../wxcomponents/wxml-to-canvas/index";
import moment from "moment";
const app = getApp();
export default {
    components: {
        Signature,
        wxmlToCanvas,
    },
    props: {
        info: {
            type: Object,
            default: {},
        },
        visible: {
            type: Boolean,
            default: false,
        },
    },
    data() {
        return {
            imgs: app.globalData.imgs,
            signatureVisible: false,
            url: "", // 签名图片url
            contractImg: "", // 合同图片本地路径
            loading: false, // 合同上传中
            today: moment().format("YYYY.MM.DD"),
            style: {
                contractImgBox: {
                    position: "relative",
                    width: 300,
                    height: 1228,
                },
                contractImg: {
                    width: 300,
                    height: 1228,
                },
                contractTitleName: {
                    position: "absolute",
                    fontSize: 10,
                    width: 100,
                    height: 10,
                    top: 68,
                    left: 65,
                },
                contractParkingName: {
                    position: "absolute",
                    fontSize: 8,
                    width: 150,
                    height: 10,
                    top: 223,
                    left: 125,
                },
                contractName: {
                    position: "absolute",
                    fontSize: 8,
                    width: 100,
                    height: 10,
                    top: 250,
                    left: 120,
                },
                contractId: {
                    position: "absolute",
                    fontSize: 8,
                    width: 100,
                    height: 10,
                    top: 264,
                    left: 120,
                },
                contractPhone: {
                    position: "absolute",
                    fontSize: 8,
                    width: 100,
                    height: 10,
                    top: 277,
                    left: 120,
                },
                contractPlate: {
                    position: "absolute",
                    fontSize: 8,
                    width: 100,
                    height: 10,
                    top: 210,
                    left: 125,
                },
                contractMonth: {
                    position: "absolute",
                    fontSize: 8,
                    width: 100,
                    height: 10,
                    top: 235,
                    left: 120,
                },
                contractStart: {
                    position: "absolute",
                    fontSize: 6,
                    width: 100,
                    height: 10,
                    top: 237,
                    left: 165,
                },
                contractEnd: {
                    position: "absolute",
                    fontSize: 6,
                    width: 100,
                    height: 10,
                    top: 237,
                    left: 210,
                },
                contractTotalPrice: {
                    position: "absolute",
                    fontSize: 6,
                    width: 100,
                    height: 10,
                    top: 315,
                    left: 180,
                },
                contractPrice: {
                    position: "absolute",
                    fontSize: 6,
                    width: 100,
                    height: 10,
                    top: 330,
                    left: 220,
                },
                contractPriceUpper: {
                    position: "absolute",
                    fontSize: 6,
                    width: 100,
                    height: 10,
                    top: 343,
                    left: 100,
                },
                contractTime1: {
                    position: "absolute",
                    fontSize: 8,
                    width: 100,
                    height: 10,
                    bottom: 26,
                    left: 90,
                },
                contractTime2: {
                    position: "absolute",
                    fontSize: 8,
                    width: 100,
                    height: 10,
                    bottom: 26,
                    left: 225,
                },
                signatureImg: {
                    position: "absolute",
                    bottom: 25,
                    left: 60,
                    width: 60,
                    height: 45,
                },
            },
        };
    },
    created() {
        this.widget = this.selectComponent(".widget");
    },
    methods: {
        upperMoney(account) {
            const money = Math.floor(account); // 金额保留整数
            // 汉字的数字
            const cnNums = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"];
            // 基本单位
            const cnIntRadice = ["", "拾", "佰", "仟"];
            // 对应整数部分扩展单位
            const cnIntUnits = ["", "万", "亿", "兆"];
            // 对应小数部分单位
            const cnDecUnits = ["角", "分", "毫", "厘"];
            // 整数金额时后面跟的字符
            const cnInteger = "";
            // 整型完以后的单位
            const cnIntLast = "元";
            // 最大处理的数字
            const maxNum = 9999999999999.99;
            // 金额整数部分
            let integerNum = "";
            // 金额小数部分
            let decimalNum = "";
            // 输出的中文金额字符串
            let chineseStr = "";
            // 分离金额后用的数组，预定义
            let parts;
            if (money >= maxNum) {
                // 超出最大处理数字
                return "";
            }
            if (money === 0) {
                chineseStr = cnNums[0] + cnIntLast + cnInteger;
                return chineseStr;
            }
            // 转换为字符串
            let moneyStr = money.toString();
            if (money < 0) {
                // 负数判断
                moneyStr = moneyStr.slice(1);
            }
            if (moneyStr.indexOf(".") === -1) {
                integerNum = moneyStr;
                decimalNum = "";
            } else {
                parts = moneyStr.split(".");
                integerNum = parts[0];
                decimalNum = parts[1];
            }
            // 获取整型部分转换
            if (parseInt(integerNum, 10) > 0) {
                let zeroCount = 0;
                const IntLen = integerNum.length;
                for (let i = 0; i < IntLen; i += 1) {
                    const n = integerNum.substring(i, i + 1);
                    const p = IntLen - i - 1;
                    const q = p / 4;
                    const m = p % 4;
                    if (n === "0") {
                        zeroCount += 1;
                    } else {
                        if (zeroCount > 0) {
                            chineseStr += cnNums[0];
                        }
                        // 归零
                        zeroCount = 0;
                        chineseStr += cnNums[parseInt(n, 10)] + cnIntRadice[m];
                    }
                    if (m === 0 && zeroCount < 4) {
                        chineseStr += cnIntUnits[q];
                    }
                }
                chineseStr += cnIntLast;
            }
            // 小数部分
            if (decimalNum !== "") {
                const decLen = decimalNum.length;
                for (let i = 0; i < decLen; i += 1) {
                    const n = decimalNum.substring(i, i + 1);
                    if (n !== "0") {
                        chineseStr += cnNums[Number(n)] + cnDecUnits[i];
                    }
                }
            }
            if (chineseStr === "") {
                chineseStr += cnNums[0] + cnIntLast + cnInteger;
            } else if (decimalNum === "") {
                chineseStr += cnInteger;
            }
            return (money < 0 ? "负" : "") + chineseStr;
        },
        // 重新签名
        reSign() {
            if (this.loading) return false;
            this.signatureVisible = true;
        },
        // 签名成功回调
        onSuccess(url) {
            this.signatureVisible = false;
            this.url = url;
            this.createContract();
        },
        // 确认提交
        confirm() {
            if (this.loading) return false;
            this.uploadContract();
        },
        // 生成合同临时图片
        createContract() {
            wx.showLoading({
                title: "合同生成中",
            });
            const wxml = `
                <view class="contractImgBox">
                    <image mode="aspectFit" class="contractImg" src="${this.imgs.contract}" />
                    <text class="contractParkingName">${this.info.dadaParkName}</text>
                    <text class="contractName">${this.info.fullName}</text>
                    <text class="contractId">${this.info.idNumber}</text>
                    <text class="contractPhone">${this.info.phone}</text>
                    <text class="contractPlate">${this.info.carNumber}</text>
                    <text class="contractMonth">${this.info.number}</text>
                    <text class="contractStart">${this.info.beginTime}</text>
                    <text class="contractEnd">${this.info.endTime}</text>
                    <text class="contractTotalPrice">${this.info.price * this.info.number}</text>
                    <text class="contractPrice">${this.info.price}</text>
                    <text class="contractPriceUpper">${this.upperMoney(this.info.price)}</text>
                    <text class="contractTime1">${this.today}</text>
                    <image mode="aspectFit" class="signatureImg" src="${this.url}" />
                </view>
            `;
            this.widget
                .renderToCanvas({ wxml, style: this.style })
                .then((res) => {
                    console.log(res);
                    return this.widget.canvasToTempFilePath();
                })
                .then((res) => {
                    this.contractImg = res.tempFilePath;
                    wx.hideLoading();
                });
        },
        // 上传合同文件
        uploadContract() {
            if (this.loading) return false;
            wx.showLoading({
                title: "加载中",
            });
            this.loading = true;
            wx.uploadFile({
                url: `${baseUrl()}/app/file/upload`,
                filePath: this.contractImg,
                name: "file",
                success: (res3) => {
                    // 网络层 状态判断
                    if (res3.statusCode !== 200) {
                        wx.showToast({
                            title: "上传合同错误",
                            icon: "none",
                        });
                        return false;
                    }

                    // 业务层 状态判断
                    let data = JSON.parse(res3.data);
                    if (data.code !== 200) {
                        wx.showToast({
                            title: "上传合同接口错误",
                            icon: "none",
                        });
                        return false;
                    }

                    let contractUrl = baseUrl() + data.data;
                    console.log("带签名的合同url", contractUrl);

                    wx.showToast({
                        title: "上传成功",
                        icon: "success",
                    });

                    console.log(contractUrl);
                    this.$emit("success", contractUrl);
                },
                fail: (err) => {
                    console.log(err);
                    wx.showToast({
                        title: "上传合同文件失败",
                        icon: "none",
                    });
                },
                complete: () => {
                    this.loading = false;
                },
            });
        },
    },
};
</script>
<style scoped lang="scss">
.contract-container {
    position: relative;
    width: 0;
    height: 0;
    .contract-modal {
        border-top-left-radius: 20rpx;
        border-top-right-radius: 20rpx;
        overflow: hidden;
    }
    .widget {
        position: fixed;
        left: -10000rpx;
    }
    .contract-content {
        width: 100%;
        height: 60vh;
        overflow: auto;
        box-sizing: border-box;
        margin-top: 100rpx;
        .contract-img-box {
            position: relative;
            width: 100%;
            height: 409vw;
            box-sizing: border-box;
            .contract-title-name {
                position: absolute;
                top: 4.5%;
                left: 25%;
                font-size: 22rpx;
            }
            .contract-parking-name {
                position: absolute;
                top: 18%;
                left: 41%;
                font-size: 20rpx;
            }
            .contract-name {
                position: absolute;
                top: 20.3%;
                left: 42%;
                font-size: 20rpx;
            }
            .contract-id {
                position: absolute;
                top: 21.3%;
                left: 39%;
                font-size: 20rpx;
            }
            .contract-phone {
                position: absolute;
                top: 22.4%;
                left: 39.2%;
                font-size: 20rpx;
            }
            .contract-plate {
                position: absolute;
                top: 17%;
                left: 38.5%;
                font-size: 20rpx;
            }
            .contract-month {
                position: absolute;
                top: 19.2%;
                left: 41%;
                font-size: 20rpx;
            }
            .contract-start {
                position: absolute;
                top: 19.3%;
                left: 55%;
                font-size: 17rpx;
            }
            .contract-end {
                position: absolute;
                top: 19.3%;
                left: 69%;
                font-size: 17rpx;
            }
            .contract-total-price {
                position: absolute;
                top: 25.5%;
                left: 60%;
                font-size: 20rpx;
            }
            .contract-price {
                position: absolute;
                top: 26.7%;
                left: 74%;
                font-size: 20rpx;
            }
            .contract-price-upper {
                position: absolute;
                top: 27.7%;
                left: 33.7%;
                font-size: 20rpx;
            }
            .contract-time1 {
                position: absolute;
                top: 97%;
                left: 31%;
                font-size: 20rpx;
            }
            .contract-time2 {
                position: absolute;
                top: 86.2%;
                left: 71%;
                font-size: 20rpx;
            }
            .contract-img {
                width: 100%;
                height: 409vw;
                object-fit: contain;
            }
            .signature-img {
                width: 100rpx;
                height: 75rpx;
                position: absolute;
                bottom: 95rpx;
                left: 200rpx;
            }
        }
    }
    .contract-footer {
        padding: 40rpx 30rpx 60rpx;
        display: flex;
        align-items: center;
        justify-content: space-between;
        .contract-btn {
            width: 50%;
            height: 80rpx;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 40rpx;
            font-size: 28rpx;
            left: 1;
            &.cancel {
                flex: 1;
                background-color: #009cff;
                margin-right: 30rpx;
                color: #fff;
            }
            &.confirm {
                flex: 2;
                background-color: #4bd1a0;
                color: #fff;
            }
        }
    }
}
</style>
